package fido;

import fido.exceptions.IncorrectCookieException;
import fido.exceptions.NotConfiguredException;
import org.mymediadb.api.mmdb.model.Movie;

import java.io.File;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: Anders
 * Date: 07.07.11
 */
public class Fido {
    private static Fido fidoInstance = null;

    private UserInterface ui;
    private String downloadLocation;

    /**
     * Remember to call Fido.setUserInterface(UserInterface ui) before using this class.
     */
    private Fido() {
        ui = new DummyUIController();
    }

    public void setUserInterface(UserInterface ui) {
        this.ui = ui;
    }

    public static Fido instance() {
        if (fidoInstance == null) {
            fidoInstance = new Fido();
        }
        return fidoInstance;
    }

    public void setDownloadLocation(String downloadLocation) {
        this.downloadLocation = downloadLocation;
    }

    /**
     * PreCriteria:
     * Fido.setDownloadLocation(); is set.
     *
     * @param movies to be downloaded
     */
    public void goFetch(List<Movie> movies) {
        if (downloadLocation == null) {
            throw new IllegalArgumentException("Set download location first!");
        }

        File testDirectory = new File(downloadLocation);
        if (!(testDirectory.isDirectory() && testDirectory.exists())) {
            throw new IllegalArgumentException("Download location is invalid!");
        }

        TorrentSites torrentSites = TorrentSites.instance();
        if (torrentSites.getSelectedTorrentSitesCount() <= 0) {

            throw new IllegalArgumentException("No tracker selected.");
        }

        ui.fidoStartedFetching();

        try {
            ui.showMessage("Searching with: " + torrentSites.getAllSelectedSitesAsString());
            for (Movie movie : movies) {
                ui.fidoIsAttemptingToFetch(movie);
                try {
                    downloadMovie(movie);
                } catch (Exception e) {
                    ui.showMessage("File for " + movie.getName() + " not saved due to: " + e.getMessage());
                }
            }
            ui.showMessage("Finished searching with: " + torrentSites.getAllSelectedSitesAsString());
        } catch (Exception e) {
            ui.showMessage("Aborted: " + e.getMessage());
        } finally {
            finishedSearching();
        }

    }

    public void downloadMovie(Movie movie) {
        TorrentSites torrentSites = TorrentSites.instance();
        if (downloadLocation == null) {
            throw new IllegalArgumentException("Set download location first!");
        }

        Torrent torrent;
        File file;

        torrent = torrentSites.getATorrent(movie);
        if (torrent != null) {
            ui.showMessage(" Woof.  Found torrent for " + movie.getName() + " ->" + torrent.getName());
            try {
                String filename = getFileName(downloadLocation + movie.getMediaId(), "torrent");
                file = torrent.download(filename);//Download that torrent
                if (file != null) {

                    ui.fidoFetchedMovie(movie, torrent);

                    ui.showMessage("Setting " + movie.getName() + " as acquired in Mymediadb.org");
                    MmdbUtils.setMovieAsAcquired(movie);
                }
            } catch (Exception e) {
                ui.showMessage("Error: " + e.getMessage() + ". Occured when attempting do download/save torrent for: " + movie.getName());
            }

        } else {
            ui.fidoCouldNotFetch(movie, torrentSites.getAllSelectedSitesAsString());
        }
    }

    private String getFileName(String fileName, String fileExtension) {
        String newFilename = fileName + "." + fileExtension;
        File file = new File(newFilename);
        int i = 1;
        while (file.exists()) {
            newFilename = fileName + "(" + i + ")" + "." + fileExtension;
            i++;
            file = new File(newFilename);
        }
        return newFilename;
    }

    private void finishedSearching() {
        ui.fidoFinishedSearching();
    }
}